#include "main.h"
int init_stack(Stack* s) {
    (*s) = malloc(sizeof(struct stack));
    int* p = (int*)malloc(sizeof((*s)->base) * STACK_MAX_SIZE);
    (*s)->base = p;
    if (!(*s)->base) {
        //printf("错误");
        return 1;
    }

    (*s)->top = (*s)->base;
    (*s)->number_of_elements = 0;
    return 0;
}
bool is_operand(char symbol) {
    if (symbol <= '9' && symbol >= '1')return 1;
    return 0;
}
bool is_operator(char symbol) {
    if (symbol == '+' || symbol == '-' || symbol == '/' || symbol == '*' || symbol == '(' || symbol == ')' || symbol == '#')return 1;
    return 0;
}
int charTurn(char operator) {
    switch (operator) {
            case '0':return 0;
            case '1':return 1;
            case '2':return 2;
            case '3':return 3;
            case '4':return 4;
            case '5':return 5;
            case '6':return 6;
            case '7':return 7;
            case '8':return 8;
            case '9':return 9;
    }
        return 0;
}
int push(Stack s, char operator_or_operand) {
    if (s->top - s->base == STACK_MAX_SIZE) {
        return 1;
    }
    if (is_operator(operator_or_operand))
    {
        *(s->top) = operator_or_operand;
    }
    else if (is_operand(operator_or_operand)) {
        *(s->top) = charTurn(operator_or_operand);
    }
    else {
        *(s->top) = operator_or_operand;
    }
    s->top++;
    s->number_of_elements++;
    return 0;
};
int pop(Stack s, char* p_operator_or_operand) {
    if (s->top == s->base) {
        return 0;
    }
    --s->top;
    *p_operator_or_operand = *(s->top);
    s->number_of_elements--;
    return 1;
}
int get_top(Stack s, char* result) {
    if (s->base == s->top) {
        return 1;
    }
    *result = *(s->top - 1);
    return 0;

}
char compare(char a, char b) {
    char sign = ' ';

    if (a == '-' || a == '+') {
        if (b == '+' || b == '-' || b == ')' || b == '#')
        {
            sign = '>';
            return sign;
        }
        else
        {
            sign = '<';
            return sign;
        }
    }
    else if (a == '*' || a == '/') {
        if (b == '(')
        {
            sign = '<';
            return sign;
        }
        else {
            sign = '>';
            return sign;
        }
    }
    else if (a == '(') {
        if (b == ')')
        {
            sign = '=';
            return sign;
        }
        else if (b == '#') {
            return 'f';
        }
        else {
            sign = '<';
            return sign;
        }

    }
    else if (a == ')') {
        if (b == '(') {
            return 'f';
        }
        else {
            sign = '>';
            return sign;
        }
    }
    else if (a == '#') {
        if (b == ')') {
            return 'f';
        }
        else if (b == '#')
        {
            sign = 'y';
            return sign;
        }
        else {
            sign = '<';
            return sign;
        }
    }
    return 'f';
}
int operation(int a, int b, char c) {
    switch (c) {
        case '+':return a + b;
        case '-':return a - b;
        case '*':return a * b;
        case '/':return a / b;
    }
    return 0;
}
// 最主要的函数，用于计算表达式的值，比如#3*(2+6)/4#。
// 返回值表示求值状态：0，合法表达式，成功求值；1，表达式不合法。
// result变量用于返回计算结果。
int evaluate(char* expression, int* result) {
    Stack s1, s2;
    int Num1, Num2;
    char a, b;
    char symbol, oper;
    char ch;
    init_stack(&s1);
    init_stack(&s2);
    push(s2, *expression);
    ch = *(++expression);
    while (1) {
        if (is_operand(ch)) {
            push(s1, ch);
        }
        else if (is_operator(ch)) {
            get_top(s2, &symbol);
            switch (compare(symbol, ch)) {
                case '>':
                    pop(s1, &a);
                    Num1 = (int)a;
                    pop(s1, &b);
                    Num2 = (int)b;
                    pop(s2, &symbol);
                    oper = (char)operation(Num2, Num1, symbol);
                    push(s1, oper);
                    get_top(s2, &symbol);
                    expression--;
                    break;
                case '<':
                    push(s2, ch);
                    break;
                case '=':
                    pop(s2, &symbol);
                    get_top(s2, &symbol);
                    break;
                case 'f':
                    return 1;
            }
        }
        else {
            break;
        }
        ch = *(++expression);
    }

    get_top(s1, &symbol);
    *result = symbol;
    return 1;
}
int main() {
    char* expression = "#3*(2+6)/4#";
    int result = 0;
    if (evaluate(expression, &result)) {
        printf("计算结果:%d\n", result);
    };
}